home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / TinyGL / ami / content / ad709 / tinygl / src / matrix.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-15  |  5.0 KB  |  267 lines

  1. /*$T matrix.c GC 1.137 08/09/02 17:47:18 */
  2.  
  3. /*$6
  4.  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5.  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6.  */
  7.  
  8. #include "zgl.h"
  9.  
  10. /* */
  11.  
  12. void gl_print_matrix(const float *m) {
  13.     int i;
  14.     /*~~*/
  15.  
  16.     for(i = 0; i < 4; i++) {
  17.         fprintf(stderr, "%f %f %f %f\n", m[i], m[4 + i], m[8 + i], m[12 + i]);
  18.     }
  19. }
  20.  
  21. /* */
  22. static inline void gl_matrix_update(GLContext *c) {
  23.     c->matrix_model_projection_updated = (c->matrix_mode <= 1);
  24. }
  25.  
  26. /* */
  27. void glopMatrixMode(GLContext *c, GLParam *p) {
  28.     int mode = p[1].i;
  29.     switch(mode) {
  30.     case GL_MODELVIEW:    c->matrix_mode = 0; break;
  31.     case GL_PROJECTION: c->matrix_mode = 1; break;
  32.     case GL_TEXTURE:    c->matrix_mode = 2; break;
  33.     default:            assert(0);
  34.     }
  35. }
  36.  
  37. /* */
  38. void glopLoadMatrix(GLContext *c, GLParam *p) {
  39.     M4        *m;
  40.     int        i;
  41.  
  42.     GLParam *q;
  43.  
  44.     m = c->matrix_stack_ptr[c->matrix_mode];
  45.     q = p + 1;
  46.  
  47.     for(i = 0; i < 4; i++) {
  48.         m->m[0][i] = q[0].f;
  49.         m->m[1][i] = q[1].f;
  50.         m->m[2][i] = q[2].f;
  51.         m->m[3][i] = q[3].f;
  52.         q += 4;
  53.     }
  54.  
  55.     gl_matrix_update(c);
  56. }
  57.  
  58. /* */
  59. void glopLoadIdentity(GLContext *c, GLParam *p) {
  60.     gl_M4_Id(c->matrix_stack_ptr[c->matrix_mode]);
  61.  
  62.     gl_matrix_update(c);
  63. }
  64.  
  65. /* */
  66. void glopMultMatrix(GLContext *c, GLParam *p) {
  67.     M4        m;
  68.     int        i;
  69.  
  70.     GLParam *q;
  71.     q = p + 1;
  72.  
  73.     for(i = 0; i < 4; i++) {
  74.         m.m[0][i] = q[0].f;
  75.         m.m[1][i] = q[1].f;
  76.         m.m[2][i] = q[2].f;
  77.         m.m[3][i] = q[3].f;
  78.         q += 4;
  79.     }
  80.  
  81.     gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
  82.  
  83.     gl_matrix_update(c);
  84. }
  85.  
  86. /* */
  87. void glopPushMatrix(GLContext *c, GLParam *p) {
  88.     int n = c->matrix_mode;
  89.     M4    *m;
  90.  
  91.     assert((c->matrix_stack_ptr[n] - c->matrix_stack[n] + 1) < c->matrix_stack_depth_max[n]);
  92.  
  93.     m = ++c->matrix_stack_ptr[n];
  94.  
  95.     gl_M4_Move(&m[0], &m[-1]);
  96.  
  97.     gl_matrix_update(c);
  98. }
  99.  
  100. /* */
  101. void glopPopMatrix(GLContext *c, GLParam *p) {
  102.     int n = c->matrix_mode;
  103.  
  104.     assert(c->matrix_stack_ptr[n] > c->matrix_stack[n]);
  105.     c->matrix_stack_ptr[n]--;
  106.     gl_matrix_update(c);
  107. }
  108.  
  109. /* */
  110. void glopRotate(GLContext *c, GLParam *p) {
  111.     M4        m;
  112.     float    u[3];
  113.     float    angle;
  114.     int        dir_code;
  115.  
  116.     angle = p[1].f * M_PI / 180.0;
  117.     u[0] = p[2].f;
  118.     u[1] = p[3].f;
  119.     u[2] = p[4].f;
  120.  
  121.     /* simple case detection */
  122.     dir_code = ((u[0] != 0) << 2) | ((u[1] != 0) << 1) | (u[2] != 0);
  123.  
  124.     switch(dir_code) {
  125.     case 0:
  126.         gl_M4_Id(&m);
  127.         break;
  128.     case 4:
  129.         if(u[0] < 0) {
  130.             angle = -angle;
  131.         }
  132.  
  133.         gl_M4_Rotate(&m, angle, 0);
  134.         break;
  135.     case 2:
  136.         if(u[1] < 0) {
  137.             angle = -angle;
  138.         }
  139.  
  140.         gl_M4_Rotate(&m, angle, 1);
  141.         break;
  142.     case 1:
  143.         if(u[2] < 0) {
  144.             angle = -angle;
  145.         }
  146.  
  147.         gl_M4_Rotate(&m, angle, 2);
  148.         break;
  149.     default: {
  150.             float    cost, sint;
  151.  
  152.             /* normalize vector */
  153.             float    len = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
  154.             if(len == 0.0f) {
  155.                 return;
  156.             }
  157.  
  158.             len = 1.0f / sqrt(len);
  159.             u[0] *= len;
  160.             u[1] *= len;
  161.             u[2] *= len;
  162.  
  163.             /* store cos and sin values */
  164.             cost = cos(angle);
  165.             sint = sin(angle);
  166.  
  167.             /* fill in the values */
  168.             m.m[3][0] = m.m[3][1] = m.m[3][2] = m.m[0][3] = m.m[1][3] = m.m[2][3] = 0.0f;
  169.             m.m[3][3] = 1.0f;
  170.  
  171.             /* do the math */
  172.             m.m[0][0] = u[0] * u[0] + cost * (1 - u[0] * u[0]);
  173.             m.m[1][0] = u[0] * u[1] * (1 - cost) - u[2] * sint;
  174.             m.m[2][0] = u[2] * u[0] * (1 - cost) + u[1] * sint;
  175.             m.m[0][1] = u[0] * u[1] * (1 - cost) + u[2] * sint;
  176.             m.m[1][1] = u[1] * u[1] + cost * (1 - u[1] * u[1]);
  177.             m.m[2][1] = u[1] * u[2] * (1 - cost) - u[0] * sint;
  178.             m.m[0][2] = u[2] * u[0] * (1 - cost) - u[1] * sint;
  179.             m.m[1][2] = u[1] * u[2] * (1 - cost) + u[0] * sint;
  180.             m.m[2][2] = u[2] * u[2] + cost * (1 - u[2] * u[2]);
  181.         }
  182.     }
  183.  
  184.     gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
  185.  
  186.     gl_matrix_update(c);
  187. }
  188.  
  189. /* */
  190. void glopScale(GLContext *c, GLParam *p) {
  191.     float    *m;
  192.     float    x = p[1].f, y = p[2].f, z = p[3].f;
  193.  
  194.     m = &c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
  195.  
  196.     m[0] *= x;
  197.     m[1] *= y;
  198.     m[2] *= z;
  199.     m[4] *= x;
  200.     m[5] *= y;
  201.     m[6] *= z;
  202.     m[8] *= x;
  203.     m[9] *= y;
  204.     m[10] *= z;
  205.     m[12] *= x;
  206.     m[13] *= y;
  207.     m[14] *= z;
  208.     gl_matrix_update(c);
  209. }
  210.  
  211. /* */
  212. void glopTranslate(GLContext *c, GLParam *p) {
  213.     float    *m;
  214.     float    x = p[1].f, y = p[2].f, z = p[3].f;
  215.  
  216.     m = &c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
  217.  
  218.     m[3] = m[0] * x + m[1] * y + m[2] * z + m[3];
  219.     m[7] = m[4] * x + m[5] * y + m[6] * z + m[7];
  220.     m[11] = m[8] * x + m[9] * y + m[10] * z + m[11];
  221.     m[15] = m[12] * x + m[13] * y + m[14] * z + m[15];
  222.  
  223.     gl_matrix_update(c);
  224. }
  225.  
  226. /* */
  227. void glopFrustum(GLContext *c, GLParam *p) {
  228.     float    *r;
  229.     M4        m;
  230.     float    left = p[1].f;
  231.     float    right = p[2].f;
  232.     float    bottom = p[3].f;
  233.     float    top = p[4].f;
  234.     float    near = p[5].f;
  235.     float    farp = p[6].f;
  236.     float    x, y, A, B, C, D;
  237.  
  238.     x = (2.0 * near) / (right - left);
  239.     y = (2.0 * near) / (top - bottom);
  240.     A = (right + left) / (right - left);
  241.     B = (top + bottom) / (top - bottom);
  242.     C = -(farp + near) / (farp - near);
  243.     D = -(2.0 * farp * near) / (farp - near);
  244.  
  245.     r = &m.m[0][0];
  246.     r[0] = x;
  247.     r[1] = 0;
  248.     r[2] = A;
  249.     r[3] = 0;
  250.     r[4] = 0;
  251.     r[5] = y;
  252.     r[6] = B;
  253.     r[7] = 0;
  254.     r[8] = 0;
  255.     r[9] = 0;
  256.     r[10] = C;
  257.     r[11] = D;
  258.     r[12] = 0;
  259.     r[13] = 0;
  260.     r[14] = -1;
  261.     r[15] = 0;
  262.  
  263.     gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
  264.  
  265.     gl_matrix_update(c);
  266. }
  267.